مشخصات مقاله
-
3996
-
0.0
-
5046
-
0
-
0
پایگاه داده ی SQlite و content provider (قسمت چهارم)
دوره آموزش برنامه نویسی اندروید
کلیه حقوق مادی و معنوی این مقاله متعلق به آموزشگاه تحلیل داده می باشد و هر گونه استفاده غیر قانونی از آن پیگرد قانونی دارد.
استفاده از پایگاه داده ی SQlite (بخش چهارم)
کلاس Loader
هدف و کاربرد کلاس Loader
کلاس گفته شده قابلیت بارگذاری داده ها را به طور ناهمگام در یک activity یا fragment برای برنامه نویس فراهم می کند. در نتیجه fragment و activity قادر خواهند بود با نظارت مداوم بر منبع اطلاعات (data source)، در صورت تغییر محتوا، نتایج جدید ارائه بدند. همچنین این امکان بوجود می آید که داده ها بین تغییراتی که در پیکربندی صورت می گیرد (config change) ماندگار شوند.
اگر Loader نتیجه را پس از اینکه شی از والدش (activity یا fragment) گسسته شد بازیابی کرد، در آن صورت قادر خواهد بود داده های مورد نظر را در حافظه ی پنهان (cache) ذخیره کند.
Loader ها برای اولین بار در ویرایش 3.0اندروید معرفی شده و از نسخه ی 1.6 به بعد اندروید جزئی از compatibility layer (لایه ی سازگاری) این سیستم عامل محسوب می شود.
پیاده سازی کلاس Loader
می توانید از کلاس انتزاعی AsynchTaskLoader جت پیاده سازی Loader بهره بگیرید.
LoaderManager یک activity یا fragment قادر است یک یا چند نمونه ی Loader را مدیریت کند. ایجاد Loader با فراخوانی متد زیر انجام می پذیرد.
# start a new loader or re-connect to existing one
getLoaderManager().initLoader(0، null، this);
اولین پارامتر شناسه ای یکتا است که توسط کلاس بازفراخوانی (callback class) جهت شناسایی Loader، بعدها مورد استفاده قرار می گیرد. دومین پارامتر در حقیقت یک Bundle است که برای اطلاعات بیشتر در اختیار کلاس بازفراخوانی قرار می گیرد.
سومین پارامتر متد initLoader () کلاسی است که به محض آغاز فرایند مقداردهی اولیه فراخوانده می شود (callback class). کلاس ذکر شده باید رابط LoaderManager.LoaderCallbacks را پیاده سازی کند. بهتر است fragment یا activity ای که از کلاس Loader بهره می گیرد، رابط LoaderManager.LoaderCallbacks را پیاده سازی کند.
Loader مستقیم به واسطه ی فراخوانی متد getLoaderManager().initLoader() ایجاد نمی گردد، بلکه باید توسط کلاس بازفراخوانی در متد onCreateLoader () ایجاد شود.
پس از اینکه Loader پروسه ی خواندن داده را به صورت ناهمگام به اتمام می رساند، متد onLoadFinished () از کلاس بازفراخوانی صدا زده می شود. در این بخش است که می توان رابط کاربری را بروز رسانی کرد.
پایگاه داده ی SQLite و کلاس CursorLoader
اندروید جهت مدیریت اتصالات به پایگاه داده SQLite کلاس CursorLoader را ارائه می دهد.
برای ContentProvider ای که مبنای آن پایگاه داده ی SQLite می باشد به طور معمول از کلاس CursorLoader کمک می گیریم. Loader نام برده پرس و جو از پایگاه داده (database query) را بخاطر اینکه اپلیکیشن مورد نظر مسدود (block) نشود، در نخ پس زمینه (background thread) انجام می دهد.
CursorLoader در واقع جایگزینی برای cursor هایی است که توسط Activity مدیریت می شوند و اکنون دیگر منسوخ اطلاق می گردند.
در صورتی که Cursor نامعتبر شود، متد onLoaderReset () در کلاس بازفراخوانی صدا زده می شود.
Cursor .7 و Loader
یکی از مشکلات که در دسترسی به پایگاه داده با آن روبرو می شویم، کند بودن این فرایند است و مسئله ی دیگری که با آن رو به رو می شویم این است که برنامه ی کاربردی مورد نظر باید چرخه ی حیات کامپوننت ها را به درستی در نظر بگیرد (به طور مثال هنگامی که احساس کرد تغییری در پیکربندی رخ داده cursor را باز کند و ببندد).
به منظور مدیریت چرخه ی حیات مولفه معین در نسخه های پیش از ویرایش 3.0اندروید می توانستیم از متد managedQuery () در activity ها استفاده کنیم، اما از اندروید 3.0 به بعد این روش دیگر نامناسب محسوب می شود. بنابراین جهت دسترسی به ContentProvider به خصوص از ویرایش 3.0 به بعد باید از Loader framework استفاده کنید.
کلاس SimpleCursorAdapter، که می توان آن را همراه با ListView مورد استفاده قرار داد، دارای متدی به نام swapCurser () می باشد. Loader شما قادر خواهد بود به وسیله ی متد گفته شده cursor را در تابع onLoadFinished () بروز رسانی کند.
کلاس CursorLoader، پس از اعمال هر تغییری در پیکربندی موجود، Cursor را دوباره متصل می کند.
.8 آموزش : SQLite، Content Provider اختصاصی و کلاس Loader
توضیح مختصر
نمونه ی نمایشی زیر همچنین در فروشگاه مجازی اندروید موجود می باشد. برای اینکه این برنامه ی کاربردی مورد استفاده و آزمایش کاربرهای بیشتری قرار بگیرد، ویژه ی نسخه های پیشین به خصوص ویرایش 2.3 سیستم عامل اندروید دوباره تنظیم شده است. در صورت برخوردار بودن از برنامه ی barcode scanner، می توانید با اسکن کد QR زیر مستقیم به نمونه برنامه ی مورد نظر در Android Market دستیابی پیدا کنید. لازم به ذکر است که این برنامه در نسخه های مختلف اندروید ممکن است کمی متفاوت باشد، برای مثال امکان دارد بجای ActionsBar، OptionsMenu داشته باشید و تم تا حدی با نسخه ی دیگر متفاوت باشد.
یک اپلیکیشن "To-do" ایجاد می کنیم که به کاربر اجازه می دهد برای خود تسک هایی را وارد کرده یا درنظر بگیرد. این آیتم ها در پایگاه داده ی SQLite ذخیره گشته و به واسطه ی ContentProvider قابل دسترسی می باشد.
در این بخش آموزشی منظور از تسک ها همان آیتم های "todo" می باشد.
برنامه ی کاربردی مزبور متشکل از دو activity است، یکی جهت مشاهده ی تمامی آیتم های لیست و دیگری ویژه ی ایجاد و اصلاح آیتم های معین. دو activity بالا از روش intent ها با هم ارتباط برقرار می کنند.
به منظور بارگذاری و مدیریت ناهمگام Cursor، activity main از یک Loader استفاده می کند.
برنامه ی کاربردی حاصل بدین شکل خواهد بود.
پروژه
پروژه ای به نام de.vogella.android.todos و activity ای به نام TodosOverviewActivity ایجاد کنید. حال activity دیگری به نام ToDoDetailActivity ایجاد کنید.
کلاس های ویژه ی مدیریت پایگاه داده
ابتدا پکیج de.vogella.android.todos.database را ایجاد کنید. این پکیج کلاس هایی که جهت اداره ی پایگاه داده بکار می روند را در خود ذخیره می کند.
همان طور که پیش تر ذکر شد توصیه می شود برای هر جدول، کلاسی مجزا ایجاد کنید. اگرچه بیش از یک جدول در این مثال بکار نمی رود، سعی کنید همیشه از روش گفته شده استفاده کنید. از این طریق، چنانچه شِمای پایگاه داده گسترش پیدا کرد، آماده خواهیم بود و دیگر به معضل برنمی خوریم.
کلاس زیر را که شامل ثابت هایی برای اسم جدول و ستون های آن است، ایجاد کنید.
package de.vogella.android.todos.database;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class TodoTable {
// Database table
public static final String TABLE_TODO = "todo";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_SUMMARY = "summary";
public static final String COLUMN_DESCRIPTION = "description";
// Database creation SQL statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_TODO
+ "("
+ COLUMN_ID + " integer primary key autoincrement، "
+ COLUMN_CATEGORY + " text not null، "
+ COLUMN_SUMMARY + " text not null،"
+ COLUMN_DESCRIPTION
+ " text not null"
+ ");";
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
public static void onUpgrade(SQLiteDatabase database، int oldVersion،
int newVersion) {
Log.w(TodoTable.class.getName()، "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ "، which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);
onCreate(database);
}
}
اکنون کلاس TodoDatabaseHelper را که در زیر نمایش داده شده، به وجود آورید. کلاس نام برده SQLiteOpenHelper را به ارث می برد و متدهای ایستای کلاس کمک رسانی TodoTable را فراخوانی می کند.
package de.vogella.android.todos.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class TodoDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "todotable.db";
private static final int DATABASE_VERSION = 1;
public TodoDatabaseHelper(Context context) {
super(context، DATABASE_NAME، null، DATABASE_VERSION);
}
// Method is called during creation of the database
@Override
public void onCreate(SQLiteDatabase database) {
TodoTable.onCreate(database);
}
// Method is called during an upgrade of the database،
// e.g. if you increase the database version
@Override
public void onUpgrade(SQLiteDatabase database، int oldVersion،
int newVersion) {
TodoTable.onUpgrade(database، oldVersion، newVersion);
}
}
به منظور دستیابی به پایگاه داده از ContentProvider استفاده می کنیم، دیگر جهت دسترسی به پایگاه داده، شی دسترسی به داده (DAO) مانند مثال قبل SQLite نمی نویسیم.
